

using System;
using UnityEngine;

namespace IQIGame.Onigao.Framework
{
    public struct OBBRect
    {
        public Vector3 center { private set; get; }
        public double rotation { private set; get; }
        public Vector2 halfSize { private set; get; }
        public Vector2 axissX { private set; get; }
        public Vector2 axissZ { private set; get; }

        public OBBRect(Vector3 center, Vector3 size, float yRotation)
        {
            this.center = center;
            this.halfSize = new Vector2(size.x / 2, size.z / 2);
            this.rotation = yRotation * Math.PI / 180;
            axissX = new Vector2((float)Math.Cos(rotation), -(float)Math.Sin(rotation));
            axissZ = new Vector2(-axissX.y, axissX.x);
        }

        public float Dot(Vector2 a, Vector2 b)
        {
            return Mathf.Abs(a.x * b.x + a.y * b.y);
        }

        public float GetProjectionRadius(Vector2 axis)
        {
            return (halfSize.x * Dot(axissX, axis) + halfSize.y * Dot(axissZ, axis));
        }

        private bool CheckProjection(ref OBBRect other, ref Vector2 curVector2, ref Vector2 distanceVector)
        {
            if ((GetProjectionRadius(curVector2) + other.GetProjectionRadius(curVector2)) <= Dot(distanceVector, curVector2))
            {
                return true;
            }
            return false;
        }

        public bool IsIntersecting(OBBRect other)
        {
            Vector2 distanceVector = new Vector2(center.x - other.center.x, center.z - other.center.z);

            var axiss = axissX;
            if (CheckProjection(ref other, ref axiss, ref distanceVector))
            {
                return false;
            }
            axiss = axissZ;
            if (CheckProjection(ref other, ref axiss, ref distanceVector))
            {
                return false;
            }

            axiss = other.axissX;
            if (CheckProjection(ref other, ref axiss, ref distanceVector))
            {
                return false;
            }

            axiss = other.axissZ;
            if (CheckProjection(ref other, ref axiss, ref distanceVector))
            {
                return false;
            }

            return true;
        }
    }
}
